package com.example.exception;

import com.example.util.CustomConstant;
import com.example.util.CustomUtil;
import com.example.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@ControllerAdvice // 表示当前类是基于注解的异常处理类
public class MyExceptionResolver {

    @ExceptionHandler(AccessDeniedException.class)
    public ModelAndView resolveMySQLIntegrityConstraintViolationException(HttpServletRequest request, HttpServletResponse response) {
        return commonResolver(new RuntimeException(CustomConstant.MESSAGE_ACCESS_DENIED), request, response, "system-error");
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView resolveException(Exception exception, HttpServletRequest request, HttpServletResponse response) {
        return commonResolver(exception, request, response, "system-error");
    }

    private ModelAndView commonResolver(Exception exception, HttpServletRequest request, HttpServletResponse response, String viewName) {
        // 1.判断当前请求的类型
        boolean judgeResult = CustomUtil.judgeRequestType(request);

        // 2.如果是Ajax请求
        if (judgeResult) {
            // 3.创建ResultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.createResultEntity(-1, exception.getMessage(), 0, null);

            // 4.将resultEntity转成JSON字符串
            Gson gson = new Gson();
            String json = gson.toJson(resultEntity);

            // 5.将JSON字符串作为响应体返回给浏览器
            response.setContentType("text/html;charset=UTF-8");
            try {
                response.getWriter().write(json);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 6.由于已经通过原生的response对象返回了响应, 所以不提供ModelAndAView对象
            return null;
        }

        // 7.如果不是Ajax请求, 创建ModelAndView对象
        ModelAndView modelAndView = new ModelAndView();

        // 8.将exception存入模型
        modelAndView.addObject(CustomConstant.ATTR_NAME_EXCEPTION, exception);

        // 9.设置对应的视图名称
        modelAndView.setViewName(viewName);

        return modelAndView;
    }
}
